﻿/// Author: Petr Pechovic
/// Contact: http://www.pechovic.eu
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using DotNetSources.Web.UI.Buttons.CssModel;

[assembly: WebResource("DotNetSources.Web.UI.Buttons.ButtonBase.css", "text/css", PerformSubstitution=true)]

namespace DotNetSources.Web.UI.Buttons {

    /// <summary>
    /// The BaseButton class contains the common functionality of extended buttons. To create concrete button derive from this class
    /// and specify the content which is T.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Css("DotNetSources.Web.UI.Buttons.ButtonBase.css")]
    public abstract class ButtonBase<T> : Table, IButtonControl, IPostBackEventHandler where T : Control {

        #region Controls

        private T contentControl;

        /// <summary>
        /// Content control inside the DIV.
        /// </summary>
        public T ContentControl {
            get {
                return contentControl;
            }
            set {
                contentControl = value;
            }
        }

        private Panel div;

        /// <summary>
        /// DIV as button. Specify the area for click.
        /// </summary>
        protected Panel Div {
            get {
                return div;
            }
            set {
                div = value;
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// If confirm text is not empty then display confirm box.
        /// </summary>
        public string ConfirmText {
            get {
                string str = (string)this.ViewState["ConfirmText"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["ConfirmText"] = value;
            }
        }

        /// <summary>
        /// If use this, postback won't be performed.
        /// </summary>
        public string OnClientClick {
            get {
                string str = (string)this.ViewState["OnClientClick"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["OnClientClick"] = value;
            }
        }

        /// <summary>
        /// CSS class for internal DIV.
        /// </summary>
        public new string CssClass {
            get {
                string str = (string)this.ViewState["CssClass__"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["CssClass__"] = value;
            }
        }


        #endregion

        #region To override

        /// <summary>
        /// Create content control.
        /// </summary>
        /// <returns></returns>
        protected abstract T CreateContentControl();

        #endregion

        /// <summary>
        /// Add custom CSS to DIV area.
        /// </summary>
        /// <param name="css"></param>
        protected void AddCss(string css) {
            div.CssClass = string.Format("{0} {1}", div.CssClass, css);
        }

        #region Lifecycle

        protected override void OnInit(EventArgs e) {

            div = new Panel();
            div.CssClass = "dns_btn_base";
            contentControl = CreateContentControl();
            div.Controls.Add(contentControl);

            TableRow tr = new TableRow();
            TableCell tc = new TableCell();
            tr.Cells.Add(tc);
            tc.Controls.Add(div);
            Rows.Add(tr);

            base.CellPadding = 0;
            base.CellSpacing = 0;
            
            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e) {

            
            if (ConfirmText == string.Empty) {
                if (OnClientClick == string.Empty) {
                    PostBackOptions options = new PostBackOptions(this);
                    options.PerformValidation = this.CausesValidation;
                    options.ValidationGroup = this.ValidationGroup;
                    string js = Page.ClientScript.GetPostBackEventReference(options);
                    Attributes.Add("onclick", string.Format("javascript: {0}", js));
                } else {
                    Attributes.Add("onclick", OnClientClick);
                }
            } else {
                Attributes.Add("onclick", string.Format("$find('{0}').Show('{1}', '{2}'); return false", 
                    Helper.RetypeToBoxContextPage(Page).ConfirmBoxId,
                    ConfirmText,
                    UniqueID));
            }
            RegisterCss();
            // asociate styles
            if (CssClass != string.Empty)
                div.CssClass = CssClass;
            base.OnPreRender(e);
        }

        /// <summary>
        /// Called in OnPreRender. In special cases when the control doesn't have CSS file or you just want to
        /// customize it.
        /// </summary>
        protected virtual void RegisterCss() {
            Helper.RetypeToBoxContextPage(Page).RegisterCss(this.GetType());
        }

        #endregion

        #region IButtonControl Members

        public bool CausesValidation {
            get {
                object obj = this.ViewState["CausesValidation"];
                if (obj != null) {
                    return (bool)obj;
                }
                return true;
            }
            set {
                this.ViewState["CausesValidation"] = value;
            }
        }

        public event EventHandler Click;

        public event CommandEventHandler Command;

        public string CommandArgument {
            get {
                string str = (string)this.ViewState["CommandArgument"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["CommandArgument"] = value;
            }
        }

        public string CommandName {
            get {
                string str = (string)this.ViewState["CommandName"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["CommandName"] = value;
            }
        }

        public string PostBackUrl {
            get {
                string str = (string)this.ViewState["PostBackUrl"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["PostBackUrl"] = value;
            }

        }

        /// <summary>
        /// Text.
        /// </summary>
        public string Text {
            get {
                string str = (string)this.ViewState["Text"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["Text"] = value;
            }
        }

        public string ValidationGroup {
            get {
                string str = (string)this.ViewState["ValidationGroup"];
                if (str != null) {
                    return str;
                }
                return string.Empty;
            }
            set {
                this.ViewState["ValidationGroup"] = value;
            }
        }

        #endregion

        #region IPostBackEventHandler Members

        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
            if (this.CausesValidation) {
                this.Page.Validate(this.ValidationGroup);
            }

            if (Click != null) {
                Click(this, EventArgs.Empty);
            }
            if (Command != null) {
                Command(this, new CommandEventArgs(CommandName, CommandArgument));
            }
        }

        #endregion

    }

}

